home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource3 / 126_01 / hiplot.c < prev    next >
Text File  |  1985-03-11  |  9KB  |  410 lines

  1. /*------------------------------------------------------------------*/
  2. /* Library of functions for Houston Instruments Pen Plotter DMP-7
  3.     (or other "intelligent" model).
  4.     Contributed by Eric Martz, Dept. of Microbiology,
  5.     University of Massachusetts, Amherst MA 01003
  6. */
  7. /*------------------------------------------------------------------*/
  8. /*    HIPLOT.C
  9.  
  10.         init_plot()
  11.         cinit()    /* initialize character label constants */
  12.         pen_to(h, v)
  13.         line(thickness, direction, h, v)
  14.         exchange(a, b)
  15.         pen_up()
  16.         pen_down()
  17.         textplot(s)
  18.         newline()
  19.         box(thickness)
  20.         home()
  21.         setlinetype(type)
  22.         saveat()
  23.         saveold()
  24.         restore()
  25.         xxouts(s)
  26.         xxoutc(c)
  27.         getmod()
  28.         miready()    
  29.         repeat(n)
  30.         fix_origin()
  31.         new_origin(h, v)
  32.         old_origin()
  33.         div_axis(min, max, width, count)
  34. */
  35. /*------------------------------------------------------------------*/
  36. #include "hiplot.h"
  37. /*------------------------------------------------------------------*/
  38. init_plot() {
  39.     cinit();
  40.     Xflag = YES;
  41.     xxouts(";:HA,490,0,O,");
  42.     Hold = Vold = Hat = Vat = Hold_origin = Vold_origin = 0;
  43.     Csize = 3;
  44.     Cvect = VERTICAL;
  45.     Fill_repeat = NO;
  46.     Offset = 2;
  47.     Plot_thickness = 1;
  48. /*    Vmin = 0;
  49.     Vmax = 1480;
  50.     Hmin = 0;
  51.     Hmax = 2000;    */
  52. }
  53.  
  54. /*------------------------------------------------------------------*/
  55. cinit() {        /* initialize character label constants */
  56.     int i;
  57.     Cheight[1] = 14;
  58.     Cbetlin[1] = Cheight[1]/2;
  59.     Cwidth[1] = (6 * Cheight[1])/7;
  60.  
  61.     Cthick[1] = 1;
  62.     Cthick[2] = 2;
  63.     Cthick[3] = 3;
  64.     Cthick[4] = 5;
  65.     Cthick[5] = 8;
  66.  
  67.     for (i=2; i<=5; i++) {
  68.         Cheight[i] = (2 * Cheight[i-1]);
  69.         Cwidth[i] = ((6 * Cheight[i])/7);
  70.         Cbetlin[i] = Cheight[i]/2;
  71.     }
  72.     for (i=2; i<=5; i++) {
  73.         Cheight[i] += (2 * Cthick[i]);
  74.         Cwidth[i] += (2 * Cthick[i]);
  75.     }
  76. }
  77.  
  78. /*------------------------------------------------------------------*/
  79. /* MOVES PEN TO h, v.
  80.     STORES NEW POSITION IN Hat, Vat.
  81.     STORES PREVIOUS POSITION IN Hold, Vold.
  82. */
  83. pen_to(h, v)
  84.     int h, v;
  85.     {
  86.     sprintf(Buf,",%d,%d,",h,v);
  87.     xxouts(Buf);
  88.     Hold = Hat;
  89.     Vold = Vat;
  90.     Hat = h;
  91.     Vat = v;
  92. }
  93.  
  94. /*------------------------------------------------------------------*/
  95. /* PUTS THE PEN DOWN AND DRAWS A LINE OF DESIRED THICKNESS FROM
  96. THE PRESENT POSITION TO h, v.
  97.  
  98. thickness IS THE INTEGER NUMBER OF LINE WIDTHS.
  99.  
  100. direction IS THE DIRECTION IN WHICH THE 2ND-NTH THICKNESS LINES
  101. ARE TO BE ADDED TO THE FIRST LINE, AND MUST BE 'r', 'l', 'u', OR 'd'.
  102.  
  103. Hat AND Vat AND FINAL PEN POSITION ARE SET TO h, v (DESTINATION)
  104. WITH PEN UP.
  105.  
  106. Hold AND Vold ARE SET TO THE ORIGINAL Hat, Vat (STARTING POSITION).
  107. */
  108. line(thickness, direction, h, v)
  109.     int thickness, direction, h, v;
  110.     {
  111.     int hold, vold, i;
  112.     int hstart, hstop, vstart, vstop;
  113.  
  114.     /* SAVE CURRENT POSITION AND DESTINATION OF FIRST PASS */
  115.     hstart = Hat;
  116.     vstart = Vat;
  117.     hstop = h;
  118.     vstop = v;
  119.  
  120.     hold = Hat;
  121.     vold = Vat;
  122.     Hat = h;
  123.     Vat = v;
  124.     pen_down();
  125.     pen_to(h, v);
  126.     for (i=2; i<= thickness; i++) {
  127.         switch (direction) {
  128.             case ('r'):
  129.                 h += Offset;
  130.                 hold += Offset;
  131.                 break;
  132.             case ('l'):
  133.                 h -= Offset;
  134.                 hold -= Offset;
  135.                 break;
  136.             case ('u'):
  137.                 v += Offset;
  138.                 vold += Offset;
  139.                 break;
  140.             case ('d'):
  141.                 v -= Offset;
  142.                 vold -= Offset;
  143.                 break;
  144.         }
  145.         pen_to(h, v);
  146.         exchange(&h, &hold);
  147.         exchange(&v, &vold);
  148.         pen_to(h, v);
  149.     }
  150.     pen_up();
  151.     if(thickness > 1) pen_to(hstop, vstop); /* sets Hat and Vat as desired */
  152.     Hold = hstart;
  153.     Vold = vstart;
  154. }    
  155.  
  156. /*------------------------------------------------------------------*/
  157. exchange(a, b)
  158.     int *a, *b;
  159.     {
  160.     int h;
  161.     h = *a;
  162.     *a = *b;
  163.     *b = h;
  164. }
  165.  
  166. /*------------------------------------------------------------------*/
  167. pen_up() {
  168.     xxouts(",U,");
  169. }
  170.  
  171. /*------------------------------------------------------------------*/
  172. pen_down() {
  173.     xxouts(",D,");
  174. }
  175.  
  176. /*------------------------------------------------------------------*/
  177. textplot(s)
  178. /* WRITES A STRING USING HIPLOT BUILT-IN CHARACTER FONT */
  179. /* WHEN FINISHED, LEAVES PEN AT LOWER LEFT STARTING POSITION PLUS
  180. TOP->BOTTOM THICKNESS. */
  181.     char *s;
  182.     {
  183.     int i, h, v, hsafe, vsafe;
  184.     hsafe = h = Hat;
  185.     vsafe = v = Vat;
  186.     for (i=1; YES; i++) {
  187.         pen_up();
  188.         sprintf(Buf,"S%d%d,%s_", Cvect, Csize, s);
  189.         xxouts(Buf);
  190.         if (i EQ Cthick[Csize]) break;
  191.         if (Cvect EQ VERTICAL) {
  192.             h += Offset;
  193.             v -= Offset;
  194.         }
  195.         else {
  196.             h -= Offset;
  197.             v -= Offset;
  198.         }
  199.         pen_up();
  200.         pen_to(h, v);
  201.     }
  202.     if (Cvect EQ VERTICAL) v = vsafe;
  203.     else h = hsafe;
  204.     pen_to(h, v);
  205. }
  206.  
  207. /*------------------------------------------------------------------*/
  208. newline() {
  209. /* PRODUCES THE EFFECT OF A NEWLINE WHEN PLOTTING TEXT CHARACTERS */
  210.     int h, v;
  211.     switch (Cvect) {
  212.         case (VERTICAL) :
  213. fprintf(STDERR,"hat %d  hei %d  bl %d\n",Hat, Cheight[Csize], Cbetlin[Csize]);
  214.             h = Hat + Cheight[Csize] + Cbetlin[Csize];
  215.             v = Vat;
  216.             break;
  217.         case (HORIZONTAL) :
  218.             h = Hat;
  219.             v = Vat - Cheight[Csize] + Cbetlin[Csize];
  220.             break;
  221.     }
  222.     pen_up();
  223.     pen_to(h, v); /* resets Hold, Vold, Hat, Vat */
  224. }
  225. /*------------------------------------------------------------------*/
  226. box(thickness)
  227.     int thickness;
  228.     {
  229.     pen_up();
  230.     pen_to(Hmin, Vmin);
  231.     line(thickness,'r',Hmin,Vmax);
  232.     line(thickness,'d',Hmax,Vmax);
  233.     line(thickness,'l',Hmax,Vmin);
  234.     line(thickness,'u',Hmin,Vmin);
  235.     pen_up();
  236. }
  237.  
  238. /*------------------------------------------------------------------*/
  239. home() {
  240.     xxoutc('H');
  241. }
  242.  
  243. /*------------------------------------------------------------------*/
  244. setlinetype(type)
  245.     int type;
  246.     {
  247.     sprintf(Buf,",L%d,",type);
  248.     xxouts(Buf);
  249. }
  250.     
  251. /*------------------------------------------------------------------*/
  252. saveat() {
  253.     Hsafe = Hat;
  254.     Vsafe = Vat;
  255. }
  256.  
  257. /*------------------------------------------------------------------*/
  258. saveold() {
  259.     Hsafe = Hold;
  260.     Vsafe = Vold;
  261. }
  262.     
  263. /*------------------------------------------------------------------*/
  264. restore() {
  265.     pen_to(Hsafe, Vsafe);
  266. }
  267.  
  268. /*------------------------------------------------------------------*/
  269. xxouts(s)
  270.     char *s;
  271.     {
  272.     while(*s) xxoutc(*s++);
  273. }
  274. /*------------------------------------------------------------------*/
  275. xxoutc(c)
  276. /* provides an XON XOFF protocol for sending characters to the plotter
  277. in case your BIOS doesn't have this built-in! Be sure to initialize
  278. Xflag to TRUE! */
  279.     char c;
  280.     {
  281.     int x;
  282.     do {
  283.         while (kbhit()) if ((getchar()) == '\3') exit(0);
  284.         while (miready()) {
  285.             if ((x = getmod()) == XOFF) Xflag = NO;
  286.             if (x EQ NULL) Xflag = NO;
  287.             if (x == XON) Xflag = YES;
  288.  
  289. #ifdef DEBUG
  290.             if (Debug) {
  291.                 puts(INTOREV);
  292.                 puts("<input:");
  293.                 dispchar(x);
  294.                 puts(">");
  295.                 puts(OUTAREV);
  296.             }
  297. #endif
  298.         }
  299.     } while (Xflag == NO);
  300.     putc(c,LST);
  301. #ifdef DEBUG
  302.     if (Debug) dispchar(c);
  303. #endif
  304.     if (Fill_repeat) {
  305.         *(At_repeat++) = c;
  306.         if (At_repeat EQ Buf_repeat + REBUF -1) {
  307.             fprintf(STDERR,
  308.                 "REPEAT BUFFER FULL. REPEAT WILL BE PARTIAL.\n");
  309.             Fill_repeat = NO;
  310.         }
  311.     }
  312. }    
  313. /*------------------------------------------------------------------*/
  314. /*
  315. /* Stolen from Leor Zolman's Telnet. You must #define if used. */
  316. miready()
  317.     {
  318.     return (inp(MSTAT) & MIMASK) == (MAHI ? MIMASK : 0);
  319. }
  320. /*------------------------------------------------------------------*/
  321. getmod()
  322. /* Stolen from Leor Zolman's Telnet. You must #define if used. */
  323.     {
  324.     char c;
  325.     c = inp(MDATA);
  326.     c &= '\177';
  327.     if (MRESET) outp(MSTAT,MRESETVAL);
  328.     return c;
  329. }
  330. */
  331. /*------------------------------------------------------------------*/
  332. repeat(n)
  333.     int n;
  334.     {
  335.     char *p;
  336. #ifdef DEBUG
  337.     if (Debug) fprintf(STDERR,
  338.         "Repeat buffer contains %u bytes.\n",
  339.         At_repeat - Buf_repeat);
  340. #endif
  341.     Fill_repeat = NO;
  342.     while (n--) {
  343.         new_origin(0, Offset);
  344.         for (p = Buf_repeat; p < At_repeat; p++) xxoutc(*p);
  345.     }
  346.     old_origin();
  347. }
  348. /*------------------------------------------------------------------*/
  349. /* FIXES ORIGIN AT Hmin, Vmin PERMANENTLY */
  350. fix_origin() {
  351.     pen_up();
  352.     pen_to(Hmin, Vmin);
  353.     xxouts(",O,");
  354.     Hmin = Vmin = 0;
  355. }
  356. /*------------------------------------------------------------------*/
  357. /* MOVES ORIGIN TO NEW POSITION RELATIVE TO OLD, KEEPING TRACK OF
  358.     TOTAL MOVEMENTS */
  359. new_origin(h, v)
  360.     int h, v;
  361.     {
  362.     pen_up();
  363.     pen_to(h, v);
  364.     xxouts(",O,"); /* RESET ORIGIN */
  365.     Hold_origin -= h;
  366.     Vold_origin -= v;
  367. }
  368. /*------------------------------------------------------------------*/
  369. old_origin() {
  370.     pen_up();
  371.     pen_to(Hold_origin, Vold_origin);
  372.     xxouts(",O,"); /* RESET ORIGIN */
  373.     Hold_origin = Vold_origin = 0;
  374. }
  375. /*------------------------------------------------------------------*/
  376. /* DIVIDES AN ARBITRARY RANGE (max - min)  INTO 3-5 "COMFORTABLE"
  377. DIVISIONS. SPECIFIES THE NUMBER OF DIVISIONS (*count) AND THE
  378. WIDTH OF EACH (*width). VALID ONLY FOR INTEGERS AND RANGES >= 30.
  379.  
  380. HERE IS THE RATIONALE:
  381.  
  382.     RANGE    WIDTH    DIVISION COUNT
  383.  
  384.     30-59    10        3-5
  385.     60-99    20        3-4
  386.     100-149    25        4-5
  387.     150-299    50        3-5
  388. */
  389. div_axis(min, max, width, count)
  390.     int min, max, *width, *count;
  391.     {
  392.     int tens, range;
  393.     tens = 1;
  394.     while ((max - min) > 299) {
  395.         max /= 10;
  396.         min /= 10;
  397.         tens *= 10;
  398.     }
  399.     *width = 50;
  400.     range = max - min;
  401.     if (range < 150) *width = 25;
  402.     if (range < 100) *width = 20;
  403.     if (range < 60) *width = 10;
  404.     *count = range / (*width);
  405.     *width *= tens;
  406. }
  407. /*------------------------------------------------------------------*/
  408. /*    END OF HIPLOT.C    */
  409. /*------------------------------------------------------------------*/
  410. d_origin, Vold_origin)